#include "Move.h"
        
Move::Move(int square1, int square2, Position p)
{
    from = square1;
    to = square2;
    piece = p.GetPiece(square1);
    cPiece = p.GetPiece(square2);
    this->promotion = '0';
}
        
Move::Move(int square1, int square2, Position p, char promotion) {
	from = square1;
	to = square2;
    piece = p.GetPiece(square1);
    cPiece = p.GetPiece(square2);
	this->promotion = promotion;
}
	
Move::Move(Move move) {
	this->from = move.from;
	this->to = move.to;
    piece = move.piece;
    cPiece = move.cPiece;
	this->promotion = move.promotion;
}

Move::Move(String move, Position p)
{
    this->from = Square.Get(move.Substring(0, 2));
    this->to = Square.Get(move.Substring(2, 2));
    piece = p.GetPiece(from);
    cPiece = p.GetPiece(to);
    if (move.Length == 5)
    {
        promotion = move[4];
    }
    else
    {
        promotion = '0';
    }
}

bool Move::IsEqual(Move m) {
	return ( (m.from == from) && (m.to == to) && (m.promotion == promotion));
}


//public static Move Null = new Move(128,128,'0');
        	
String Move::ToString() {
    if (promotion != '0') return Square.ToString(from) + Square.ToString(to) + promotion; 
    return Square.ToString(from) + Square.ToString(to); 
}

int Move::GetHashCode()
{
    return (from)+65*(to)+65*65*(promotion);
}



// Comparer used to do a preliminary sort of lists of legalMoves
int Move::CompareTo(object obj)
{
    // Rules:
    // 1 - captures first, then escape moves (king?), then quiet moves
    // 2 - agressive chessmen first, pawns last (except for last ranks?)

    int val = evalMoveBruitality(this);
    int valo = evalMoveBruitality((Move)obj);

    return valo - val;
}

int Move::evalMoveBruitality(Move move)
{
    // best captures first
    int captureEval = 2000*GetVal(move.cPiece);
    // lowest piece moved for capture first
    int pieceEval = 2000-GetVal(move.piece);
    return captureEval + pieceEval;
}

int Move::GetVal(Piece piece)
{
    switch (piece)
    {
        case W_KING:
        case B_KING:
            return 1900;
        case W_QUEEN:
        case B_QUEEN:
            return 900;
        case W_ROOK:
        case B_ROOK:
            return 500;
        case W_BISHOP:
        case B_BISHOP:
            return 300;
        case W_KNIGHT:
        case B_KNIGHT:
            return 300;
        case W_PAWN:
        case B_PAWN:
            return 90;
        case NO_PIECE:
        default:
            return 0;
    }
}

bool Move::IsCapture()
{
    if (this->cPiece != NO_PIECE)
        return true;
    return false;
}



